import math
from .type_conversion import TypeConversion


class ExcelFormula:

    # 大循环/主循环 每10^5循环的损伤 = POWER(((1-R_GAG)*maxGAG/(2*Mpa-(1+R_GAG)*maxGAG)),1/LOG10(D5))*10^5
    # maxGAG：最大应力
    @staticmethod
    def getCyclicDamage(S, R_GAG, maxGAG, Mpa):
        try:
            S = TypeConversion.toFloat(S)
            R_GAG = TypeConversion.toFloat(R_GAG)
            maxGAG = TypeConversion.toFloat(maxGAG)
            Mpa = TypeConversion.toFloat(Mpa)
            if S == "" or R_GAG == "" or maxGAG == "" or Mpa == "":
                return ""

            # 计算分子和分母
            numerator = (1 - R_GAG) * maxGAG
            denominator = 2 * Mpa - (1 + R_GAG) * maxGAG
            # 计算幂运算的基数
            power_base = numerator / denominator
            # 计算幂运算的指数
            exponent = 1 / math.log10(S)
            # 计算最终结果
            result = math.pow(power_base, exponent) * math.pow(10, 5)
            return result
        except Exception as e:
            print(e)
            return None

    # 小循环 每10^5循环的损伤 =10^5*(L14/(H5-K14))^(1/LOG10(D5))
    # meanStress：平均应力， stressAmplitude：应力幅
    @staticmethod
    def getCyclicDamage_minorCycle(meanStress, stressAmplitude, S, Mpa):
        try:
            meanStress = TypeConversion.toFloat(meanStress)
            stressAmplitude = TypeConversion.toFloat(stressAmplitude)
            S = TypeConversion.toFloat(S)
            Mpa = TypeConversion.toFloat(Mpa)
            if meanStress == "" or stressAmplitude == "" or S == "" or Mpa == "":
                return ""

            stressAmplitude
            denominator = Mpa - meanStress
            power_base = stressAmplitude / denominator
            exponent = 1 / math.log10(S)
            result = math.pow(power_base, exponent) * math.pow(10, 5)
            return result
        except Exception as e:
            print(e)
            return None

    # R_GAG = minGAG / maxGAG
    # minGAG: 最小应力，maxGAG：最大应力
    @staticmethod
    def getR_GAG(minGAG, maxGAG):
        try:
            minGAG = TypeConversion.toFloat(minGAG)
            maxGAG = TypeConversion.toFloat(maxGAG)
            if minGAG == "" or maxGAG == "":
                return ""
            return minGAG / maxGAG
        except Exception as e:
            print(e)
            return None

    # 大循环/主循环/小循环 每10^5飞行的损伤 = cyclicNum * cyclicDamage
    # cyclicNum: 每次飞行的循环数，cyclicDamage：每10^5循环的损伤
    @staticmethod
    def getFlightDamage(cyclicNum, cyclicDamage):
        try:
            cyclicNum = TypeConversion.toFloat(cyclicNum)
            cyclicDamage = TypeConversion.toFloat(cyclicDamage)
            if cyclicNum == "" or cyclicDamage == "":
                return None
            return cyclicNum * cyclicDamage
        except Exception as e:
            print(e)
            return None

    # 总损伤 = SUM(O14:O18)+O8+O9+O10+O11
    # majorCycleDamage: 大循环每10^5次飞行的损伤，primaryCycleDamageList：主循环每10^5循环的损伤集合，primaryCycleDamageList：小循环每10^5循环的损伤集合
    @staticmethod
    def getTotalDamage(
        majorCycleDamage, primaryCycleDamageList=[], minorCycleDamageList=[]
    ):
        try:
            majorCycleDamage = TypeConversion.toFloat(majorCycleDamage)
            if majorCycleDamage == "":
                majorCycleDamage = 0
            for i, damage in enumerate(primaryCycleDamageList):
                primaryCycleDamageList[i] = TypeConversion.toFloat(damage)
                if primaryCycleDamageList[i] == "" or primaryCycleDamageList[i] == None:
                    primaryCycleDamageList[i] = 0
            for i, damage in enumerate(minorCycleDamageList):
                minorCycleDamageList[i] = TypeConversion.toFloat(damage)
                if minorCycleDamageList[i] == "" or minorCycleDamageList[i] == None:
                    minorCycleDamageList[i] = 0
            result = (
                sum(primaryCycleDamageList)
                + sum(minorCycleDamageList)
                + majorCycleDamage
            )
            return result
        except Exception as e:
            print(e)
            return None

    # 地-空-地损伤比λ = majorCycleDamage / totalDamage
    # majorCycleDamage: 大循环每10^5次飞行的损伤，totalDamage：总损伤
    @staticmethod
    def getGAGRadio(majorCycleDamage, totalDamage):
        try:
            majorCycleDamage = TypeConversion.toFloat(majorCycleDamage)
            totalDamage = TypeConversion.toFloat(totalDamage)
            if majorCycleDamage == "" or totalDamage == "":
                return
            return majorCycleDamage / totalDamage
        except Exception as e:
            print(e)
            return None

    # R_c =IF(B25>100,"1",(250/B25)^(LOG10(D5)/L5))
    @staticmethod
    def getR_c(N_d, S, a):
        try:
            N_d = TypeConversion.toFloat(N_d)
            S = TypeConversion.toFloat(S)
            a = TypeConversion.toFloat(a)
            if N_d == "" or S == "" or a == "":
                return None

            if N_d > 100:
                result = "1"
            else:
                numerator = 250 / N_d
                exponent = math.log10(S) / a
                result = math.pow(numerator, exponent)  # 保留 4 位小数
            return result
        except Exception as e:
            print(e)
            return None

    # 修正DFRbase =DFRbase/R23*R22
    # actualStress: 实际应力集中系数，cyclicDamage：初始应力集中系数
    @staticmethod
    def getCorrectedDFRbase(DFRbase, actualStress, initialStress):
        try:
            DFRbase = TypeConversion.toFloat(DFRbase)
            actualStress = TypeConversion.toFloat(actualStress)
            initialStress = TypeConversion.toFloat(initialStress)
            if DFRbase == "" or actualStress == "" or initialStress == "":
                return None
            return DFRbase / actualStress * initialStress
        except Exception as e:
            print(e)
            return None

    # DFR = correctedDFRbase*A*B*C*D*E*F*U*R_c
    # correctedDFRbase: 修正DFRbase
    @staticmethod
    def getDFR(correctedDFRbase, A, B, C, D, E, F, U, R_c):
        try:
            params = [correctedDFRbase, A, B, C, D, E, F, U, R_c]
            for i, param in enumerate(params):
                params[i] = TypeConversion.toFloat(param)
                if params[i] == "":
                    return None
            result = 1
            for value in params:
                result *= value
            return result
        except Exception as e:
            print(e)
            return None

    # Z_GAG = (1-J8)*(H5-0.53*L25)*F8/(L25*(0.94*H5-0.47*(1+J8)*F8))
    # maxGAG：最大应力
    @staticmethod
    def getZ_GAG(R_GAG, MPa, DFR, maxGAG):
        try:
            R_GAG = TypeConversion.toFloat(R_GAG)
            MPa = TypeConversion.toFloat(MPa)
            DFR = TypeConversion.toFloat(DFR)
            maxGAG = TypeConversion.toFloat(maxGAG)
            if R_GAG == "" or MPa == "" or DFR == "" or maxGAG == "":
                return None
            # 计算公式
            numerator = (1 - R_GAG) * (MPa - 0.53 * DFR) * maxGAG
            denominator = DFR * (0.94 * MPa - 0.47 * (1 + R_GAG) * maxGAG)
            result = numerator / denominator
            return result
        except Exception as e:
            print(e)
            return None

    # N_GAG = 10^(5-LOG10(E31)/LOG10(D5))
    @staticmethod
    def getN_GAG(Z_GAG, S):
        try:
            Z_GAG = TypeConversion.toFloat(Z_GAG)
            S = TypeConversion.toFloat(S)
            if Z_GAG == "" or S == "":
                return None
            exponent = 5 - (math.log10(Z_GAG) / math.log10(S))
            result = math.pow(10, exponent)
            return result
        except Exception as e:
            print(e)
            return None

    # N_r = INT(H31*A20/A5)
    # GAGRadio: 地-空-地损伤比λ
    @staticmethod
    def getN_r(N_GAG, GAGRadio, FRF):
        try:
            N_GAG = TypeConversion.toFloat(N_GAG)
            GAGRadio = TypeConversion.toFloat(GAGRadio)
            FRF = TypeConversion.toFloat(FRF)
            if N_GAG == "" or GAGRadio == "" or FRF == "":
                return None
            result = int(N_GAG * GAGRadio / FRF)
            return result
        except Exception as e:
            print(e)
            return None
